package security.auth;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;

import org.mapdb.DB;
import org.mapdb.Serializer;

import core.engine.systemDBEngine;
import session.Session;

public class UserManager {

    // 用户权限常量
    public static final int ADMIN_LEVEL = 1;  // 管理员权限
    public static final int NORMAL_LEVEL = 2;  // 普通用户权限

    /**
     * 获取当前登录的用户
     *
     * @return 当前登录的用户名，如果未登录则返回null
     */
    public static String getCurrentUser() {
        return Session.getCurrentUser();
    }

    /**
     * 初始化用户表
     * 将在系统数据库初始化时被调用
     *
     * @param sysDB 系统数据库实例
     */
    public static void initUserTable(DB sysDB) {
        System.out.println("开始初始化用户表...");

        // 初始化用户表
        ConcurrentMap<String, String> users = sysDB
            .hashMap("users", Serializer.STRING, Serializer.STRING)
            .createOrOpen();

        // 初始化用户权限表
        ConcurrentMap<String, Integer> userLevels = sysDB
            .hashMap("user_levels", Serializer.STRING, Serializer.INTEGER)
            .createOrOpen();

        // 创建默认管理员用户
        if (!users.containsKey("admin")) {
            users.put("admin", "114514");
            userLevels.put("admin", ADMIN_LEVEL);
            System.out.println("创建默认管理员用户: admin (密码: 114514, 权限级别: " + ADMIN_LEVEL + ")");
            sysDB.commit();
        } else {
            System.out.println("默认管理员用户已存在，密码: " + users.get("admin"));

            // 确保管理员用户有正确的权限级别
            if (!userLevels.containsKey("admin") || userLevels.get("admin") != ADMIN_LEVEL) {
                userLevels.put("admin", ADMIN_LEVEL);
                System.out.println("更新管理员权限级别为: " + ADMIN_LEVEL);
                sysDB.commit();
            }
        }

        // 检验用户表是否包含admin用户
        if (users.containsKey("admin")) {
            System.out.println("验证: admin用户存在，密码=" + users.get("admin") + ", 级别=" + userLevels.get("admin"));
        } else {
            System.err.println("警告: 管理员用户未成功创建，请检查数据库权限");
        }
    }

    /**
     * 创建新用户（指定权限级别）
     *
     * @param username 用户名
     * @param password 密码
     * @param level 权限级别（1=管理员，2=普通用户）
     * @return 成功返回true，失败返回false
     */
    public static boolean createUser(String username, String password, int level) {
        if (username == null || username.trim().isEmpty() ||
            password == null || password.trim().isEmpty()) {
            return false;
        }

        if (level != ADMIN_LEVEL && level != NORMAL_LEVEL) {
            System.err.println("❌ 无效的用户权限级别: " + level + "，使用默认值 (普通用户)");
            level = NORMAL_LEVEL; // 使用普通用户作为默认权限
        }

        DB sysDB = null;
        try {
            sysDB = systemDBEngine.getSystemDB();
            // 获取用户表
            ConcurrentMap<String, String> users = sysDB
                    .hashMap("users", Serializer.STRING, Serializer.STRING)
                    .createOrOpen();

            // 获取用户权限表
            ConcurrentMap<String, Integer> userLevels = sysDB
                .hashMap("user_levels", Serializer.STRING, Serializer.INTEGER)
                .createOrOpen();

            // 检查用户是否已存在
            if (users.containsKey(username)) {
                return false;
            }

            // 添加新用户
            users.put(username, password);
            userLevels.put(username, level);
            sysDB.commit(); // 确保数据被持久化
            return true;
        } catch (Exception e) {
            System.err.println("❌ 创建用户失败: " + e.getMessage());
            return false;
        }
        // 不关闭sysDB，它由systemDBEngine管理
    }

    /**
     * 验证用户凭据
     *
     * @param username 用户名
     * @param password 密码
     * @return 验证成功返回true，失败返回false
     */
    public static boolean verifyUser(String username, String password) {
        if (username == null || username.trim().isEmpty() ||
            password == null || password.trim().isEmpty()) {
            return false;
        }

        DB sysDB = null;
        try {
            sysDB = systemDBEngine.getSystemDB();
            ConcurrentMap<String, String> users = sysDB
                    .hashMap("users", Serializer.STRING, Serializer.STRING)
                    .createOrOpen();

            // 检查用户是否存在
            if (!users.containsKey(username)) {
                return false;
            }

            // 验证密码
            String storedPassword = users.get(username);
            return password.equals(storedPassword);
        } catch (Exception e) {
            System.err.println("❌ 验证用户失败: " + e.getMessage());
            return false;
        }
        // 不关闭sysDB，它由systemDBEngine管理
    }

    /**
     * 用户登录方法
     * 验证用户名和密码，成功后创建新会话
     *
     * @param username 用户名
     * @param password 密码
     * @return 登录成功返回新建的会话，失败返回null
     */
    public static Session login(String username, String password) {
        try {
            System.out.println("尝试登录用户: " + username);

            // 验证用户是否存在
            DB sysDB = null;
            try {
                sysDB = systemDBEngine.getSystemDB();
                ConcurrentMap<String, String> users = sysDB
                        .hashMap("users", Serializer.STRING, Serializer.STRING)
                        .createOrOpen();

                if (!users.containsKey(username)) {
                    System.err.println("用户 [" + username + "] 不存在");
                    return null;
                }

                // 验证密码
                String storedPassword = users.get(username);
                System.out.println("存储的密码: " + storedPassword);

                if (!password.equals(storedPassword)) {
                    System.err.println("密码不匹配");
                    return null;
                }

                // 获取用户权限级别
                int userLevel = getUserLevel(username);
                System.out.println("用户权限级别: " + userLevel);

                // 创建并激活新会话
                Session session = new Session(username, userLevel);
                session.activate();

                System.out.println("登录成功，已创建新会话: " + session.getSessionId());
                return session;
            } catch (Exception e) {
                System.err.println("❌ 访问系统数据库失败: " + e.getMessage());
                return null;
            }
            // 不关闭sysDB，它由systemDBEngine管理
        } catch (Exception e) {
            System.err.println("❌ 登录失败，系统错误: " + e.getMessage());
            StringWriter sw = new StringWriter();
            e.printStackTrace(new PrintWriter(sw));
            System.err.println("堆栈跟踪:\n" + sw.toString().replace("\t", "    "));
            return null;
        }
    }

    /**
     * 用户登出方法
     *
     * @param session 要登出的会话
     */
    public static void logout(Session session) {
        if (session != null) {
            session.deactivate();
            System.out.println("✅ 用户 [" + session.getUsername() + "] 已成功登出系统");
        }
    }

    /**
     * 获取用户权限级别
     *
     * @param username 用户名
     * @return 用户权限级别，如果用户不存在返回-1
     */
    public static int getUserLevel(String username) {
        if (username == null || username.trim().isEmpty()) {
            return -1;
        }

        DB sysDB = null;
        try {
            sysDB = systemDBEngine.getSystemDB();
            // 获取用户权限表
            ConcurrentMap<String, Integer> userLevels = sysDB
                .hashMap("user_levels", Serializer.STRING, Serializer.INTEGER)
                .createOrOpen();

            // 获取用户权限级别
            return userLevels.getOrDefault(username, -1);
        } catch (Exception e) {
            System.err.println("❌ 获取用户权限失败: " + e.getMessage());
            return -1;
        }
        // 不关闭sysDB，它由systemDBEngine管理
    }

    /**
     * 检查用户是否为管理员
     *
     * @param username 用户名
     * @return 如果是管理员返回true，否则返回false
     */
    public static boolean isAdmin(String username) {
        return getUserLevel(username) == ADMIN_LEVEL;
    }

    /**
     * 获取并显示所有用户信息，包括用户名、密码和权限级别
     * 此方法需要管理员权限
     *
     * @param requestUsername 请求查看的用户名
     * @param pw 用于输出结果的PrintWriter
     */
    public static void showAllUsers(String requestUsername, PrintWriter pw) {
        // 检查请求者是否为管理员
        if (!isAdmin(requestUsername)) {
            pw.println("❌ 只有管理员可以查看用户列表");
            return;
        }

        Map<String, Map<String, Object>> allUsers = new HashMap<>();

        DB sysDB = null;
        try {
            sysDB = systemDBEngine.getSystemDB();
            // 获取用户表
            ConcurrentMap<String, String> users = sysDB
                .hashMap("users", Serializer.STRING, Serializer.STRING)
                .createOrOpen();

            // 获取用户权限表
            ConcurrentMap<String, Integer> userLevels = sysDB
                .hashMap("user_levels", Serializer.STRING, Serializer.INTEGER)
                .createOrOpen();

            // 合并数据
            for (Map.Entry<String, String> entry : users.entrySet()) {
                String username = entry.getKey();
                String password = entry.getValue();
                int level = userLevels.getOrDefault(username, NORMAL_LEVEL); // 默认为普通用户

                Map<String, Object> userInfo = new HashMap<>();
                userInfo.put("password", password);
                userInfo.put("level", level);
                userInfo.put("levelName", level == ADMIN_LEVEL ? "管理员" : "普通用户");

                allUsers.put(username, userInfo);
            }

            // 输出用户列表
            pw.println("\n系统用户列表:");
            pw.println("--------------------------------------------");
            pw.printf("%-15s %-10s %-10s\n", "用户名", "密码", "权限级别");
            pw.println("--------------------------------------------");

            for (Map.Entry<String, Map<String, Object>> entry : allUsers.entrySet()) {
                String username = entry.getKey();
                Map<String, Object> info = entry.getValue();

                pw.printf("%-15s %-10s %-10s\n",
                    username,
                    info.get("password"),
                    info.get("levelName"));
            }

            pw.println("--------------------------------------------");
            pw.println("总计: " + allUsers.size() + " 个用户");

        } catch (Exception e) {
            pw.println("❌ 获取用户列表失败: " + e.getMessage());
        }
        // 不关闭sysDB，它由systemDBEngine管理
    }

    /**
     * 检查用户是否存在
     *
     * @param username 用户名
     * @return 如果用户存在返回true，否则返回false
     */
    public static boolean userExists(String username) {
        if (username == null || username.trim().isEmpty()) {
            return false;
        }
        DB sysDB = null;
        try {
            sysDB = systemDBEngine.getSystemDB();
            ConcurrentMap<String, String> users = sysDB
                    .hashMap("users", Serializer.STRING, Serializer.STRING)
                    .createOrOpen();
            return users.containsKey(username);
        } catch (Exception e) {
            System.err.println("❌ 检查用户是否存在时出错: " + e.getMessage());
            return false; // 在出错时假设用户不存在或无法验证
        }
    }

}
